package com.kaibes.orm.curd;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class QueryBuilder {
    
    private HashMap<String, Object> eq;
    private HashMap<String, Object> ne;
    private HashMap<String, Object> lt;
    private HashMap<String, Object> gt;
    private HashMap<String, Object> lte;
    private HashMap<String, Object> gte;
    
    private HashMap<String, Object> like;
    private HashMap<String, Object> notLike;
    
    private List<String> nullValue;
    private List<String> notNullValue;
    
    private HashMap<String, Object[]> in;
    private HashMap<String, Object[]> notIn;
    
    private HashMap<String, Select> eqSelect;
    private HashMap<String, Select> neSelect;
    private HashMap<String, Select> inSelect;
    private HashMap<String, Select> notInSelect;
    
    private List<String> sqlList;
    private List<String> todayList;
    
    public QueryBuilder eq(String key, Object value) {
        if (eq == null) {
            eq = new HashMap<>();
        }
        eq.put(key, value);
        return this;
    }
    public QueryBuilder ne(String key, Object value) {
        if (ne == null) {
            ne = new HashMap<>();
        }
        ne.put(key, value);
        return this;
    }
    public QueryBuilder lt(String key, Object value) {
        if (lt == null) {
            lt = new HashMap<>();
        }
        lt.put(key, value);
        return this;
    }
    public QueryBuilder gt(String key, Object value) {
        if (gt == null) {
            gt = new HashMap<>();
        }
        gt.put(key, value);
        return this;
    }
    public QueryBuilder lte(String key, Object value) {
        if (lte == null) {
            lte = new HashMap<>();
        }
        lte.put(key, value);
        return this;
    }
    public QueryBuilder gte(String key, Object value) {
        if (gte == null) {
            gte = new HashMap<>();
        }
        gte.put(key, value);
        return this;
    }
    
    public QueryBuilder like(String key, Object value) {
        if (like == null) {
            like = new HashMap<>();
        }
        like.put(key, "%"+value+"%");
        return this;
    }
    public QueryBuilder notLike(String key, Object value) {
        if (notLike == null) {
            notLike = new HashMap<>();
        }
        notLike.put(key, "%"+value+"%");
        return this;
    }
    public QueryBuilder leftLike(String key, Object value) {
        if (like == null) {
            like = new HashMap<>();
        }
        like.put(key, "%"+value);
        return this;
    }
    public QueryBuilder notLeftLike(String key, Object value) {
        if (notLike == null) {
            notLike = new HashMap<>();
        }
        notLike.put(key, "%"+value);
        return this;
    }
    public QueryBuilder rightLike(String key, Object value) {
        if (like == null) {
            like = new HashMap<>();
        }
        like.put(key, value+"%");
        return this;
    }
    public QueryBuilder notRightLike(String key, Object value) {
        if (notLike == null) {
            notLike = new HashMap<>();
        }
        notLike.put(key, value+"%");
        return this;
    }
    
    public QueryBuilder nullValue(String value) {
        if (nullValue == null) {
            nullValue = new ArrayList<>();
        }
        nullValue.add(value);
        return this;
    }
    public QueryBuilder notNullValue(String value) {
        if (notNullValue == null) {
            notNullValue = new ArrayList<>();
        }
        notNullValue.add(value);
        return this;
    }
    
    public QueryBuilder inArray(String key, Object[] value) {
        if (in == null) {
            in = new HashMap<>();
        }
        in.put(key, value);
        return this;
    }
    public QueryBuilder inList(String key, List<?> value) {
        if (in == null) {
            in = new HashMap<>();
        }
        in.put(key, value.toArray());
        return this;
    }
    
    public QueryBuilder notInArray(String key, Object[] value) {
        if (notIn == null) {
            notIn = new HashMap<>();
        }
        notIn.put(key, value);
        return this;
    }
    public QueryBuilder notInList(String key, List<?> value) {
        if (notIn == null) {
            notIn = new HashMap<>();
        }
        notIn.put(key, value.toArray());
        return this;
    }
    
    public QueryBuilder eqSelect(String key, Select select) {
        if (eqSelect == null) {
            eqSelect = new HashMap<>();
        }
        eqSelect.put(key, select);
        return this;
    }
    public QueryBuilder neSelect(String key, Select select) {
        if (neSelect == null) {
            neSelect = new HashMap<>();
        }
        neSelect.put(key, select);
        return this;
    }
    
    public QueryBuilder inSelect(String key, Select select) {
        if (inSelect == null) {
            inSelect = new HashMap<>();
        }
        inSelect.put(key, select);
        return this;
    }
    public QueryBuilder notInSelect(String key, Select select) {
        if (notInSelect == null) {
            notInSelect = new HashMap<>();
        }
        notInSelect.put(key, select);
        return this;
    }
    
    public QueryBuilder sql(String sql) {
        if (sqlList == null) {
            sqlList = new ArrayList<>();
        }
        sqlList.add(sql);
        return this;
    }
    
    public QueryBuilder today(String key) {
        if (todayList == null) {
            todayList = new ArrayList<>();
        }
        todayList.add(key);
        return this;
    }
    
    public Query build() {
        Query query = new Query();
        query.setEq(eq);
        query.setNe(ne);
        query.setLt(lt);
        query.setGt(gt);
        query.setLte(lte);
        query.setGte(gte);
        query.setLike(like);
        query.setNotLike(notLike);
        query.setNullValue(nullValue);
        query.setNotNullValue(notNullValue);
        query.setIn(in);
        query.setNotIn(notIn);
        
        query.setEqSelect(eqSelect);
        query.setNeSelect(neSelect);
        query.setInSelect(inSelect);
        query.setNotInSelect(notInSelect);
        
        query.setSqlList(sqlList);
        query.setTodayList(todayList);
        
        return query;
    }
    
    public static QueryBuilder newBuilder() {
        return new QueryBuilder();
    }
    
    public static QueryBuilder newBuilder(Query query) {
        QueryBuilder builder = new QueryBuilder();
        builder.eq = query.getEq();
        builder.ne = query.getNe();
        builder.lt = query.getLt();
        builder.gt = query.getGt();
        builder.lte = query.getLte();
        builder.gte = query.getGte();
        builder.like = query.getLike();
        builder.notLike = query.getNotLike();
        builder.nullValue = query.getNullValue();
        builder.notNullValue = query.getNotNullValue();
        builder.in = query.getIn();
        builder.notIn = query.getNotIn();
        
        builder.eqSelect = query.getEqSelect();
        builder.neSelect = query.getNeSelect();
        builder.inSelect = query.getInSelect();
        builder.notInSelect = query.getNotInSelect();
        
        builder.sqlList = query.getSqlList();
        builder.todayList = query.getTodayList();
        return builder;
    }
}
